package domino;

import java.io.*;
import java.net.*;
import java.util.*;

class ConectorJuego extends Subject {

    private ArrayList<Ficha> fichas;
    private int Numero;
    private boolean conectado;
    public String Host;
    public int Puerto;
    private Socket socket;
    private PrintStream p;
    private BufferedReader b;

    public int getNumero() {
        return Numero;
    }

    public ConectorJuego(String host, int puerto) {
        super();
        this.Host = host;
        this.Puerto = puerto;
        conectado = false;
    }

    public void Conectar() {
        if (!isConectado()) {
            try {
                socket = new Socket(this.Host, this.Puerto);
                p = new PrintStream(socket.getOutputStream());
                b = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                Reader r = new Reader(b, this);
                Thread t = new Thread(r);
                t.start();
                setConectado(true);
            } catch (UnknownHostException ex) {
                this.informar("No se encontró el host " + Host);
            } catch (IOException ex) {
                this.informar("Error de E/S: " + ex.getMessage());
            }
        } else {
            this.informar("Ya está conectado");
        }
    }

    void procesarMensaje(String mensaje) {
        this.informar(mensaje);
        String[] linea = mensaje.split(":");
        if (linea.length == 2) {
            String comando = linea[0];           
            String args = linea[1];
            //Este comando se ejecuta al conectarse al servidor. El cliente recibe
            //un número de jugador consecutivo generado en el servidor.
            switch (comando) {
                case "Num":
                    Numero = Integer.parseInt(args);
                    break;
                //Este comando se ejecuta cuando se han conectado todos los jugadores necesarios
                //para una partida. El comando contiene todas las fichas que le pertenecen a
                //éste jugador.
                case "Fichas":
                    String[] strFichas = args.split(",");
                    fichas = new ArrayList<>();
                    for (int i = 0; i < strFichas.length; i++) {
                        Ficha ficha = new Ficha(strFichas[i]);
                        fichas.add(ficha);
                    }
                    this.enviarFichas(fichas);
                    break;
                case "Ficha":
                    Ficha ficha = new Ficha(args);
                    this.comerFicha(ficha);
                    fichas.add(ficha);
                    break;
                //Éste comando se recibe desde el servidor tantas veces como clientes existan
                //más uno para el tren central. Él comando incluye el estado actual de cada tren.
                case "Tren":
                    Tren t = new Tren(args);
                    this.enviarTren(t);
                    break;
                case "Motor":
                    Ficha motor = new Ficha(args);
                    this.setMotor(motor);
                    break;
                //Al recibir éste comando el Jugador obtiene el permiso de poder hacer movimientos
                //ya que inicia su turno
                case "Turno":   
                    this.informar("Es tu turno de iniciar tu jugada.");
                    this.iniciarTurno();
                    break;
                case "Puntos":
                    this.finTurno();
                    this.informar(mensaje);
                    break;
            }
        }
        this.actualizaInterfaz();        
    }

    public void Comer() {
        p.println("Comer:");
    }

    public void PonerFicha(Tren tren, Ficha ficha) {
        p.println("Poner:" + tren.getNumero() + ',' + ficha.toString());
    }

    /**
     * @return the conectado
     */
    public boolean isConectado() {
        return conectado;
    }

    /**
     * @param conectado the conectado to set
     */
    public void setConectado(boolean conectado) {
        this.conectado = conectado;
    }

    public void pasar() {            
        p.println("Pasar:");
    }
    
    public void finTurno() {            
        p.println("FinTurno:");
    }
    
    public void comenzar(){
        p.println("Comenzar");
    }
}

class Reader implements Runnable {

    BufferedReader buffer;
    ConectorJuego conector;

    public Subject getConector() {
        return conector;
    }

    public void setConector(ConectorJuego c) {
        conector = c;
    }

    public Reader(BufferedReader b, ConectorJuego c) {
        buffer = b;
        setConector(c);
    }

    @Override
    public void run() {
        while (true) {
            try {
                String respuesta = buffer.readLine();
                conector.procesarMensaje(respuesta);
            } catch (Exception ex) {
                conector.informar("Error: " + ex.getMessage());
            }
        }
    }
}